package com.gidgabs.utils;


import com.gidgabs.common.exception.RRException;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;

import java.io.*;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpsUtil {
    public static CloseableHttpClient getHttpClient() {
        try {
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            //不进行主机名验证
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build(),
                    NoopHostnameVerifier.INSTANCE);
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", new PlainConnectionSocketFactory())
                    .register("https", sslConnectionSocketFactory)
                    .build();

            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
            cm.setMaxTotal(100);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslConnectionSocketFactory)
                    .setDefaultCookieStore(new BasicCookieStore())
                    .setConnectionManager(cm).build();
            return httpclient;
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    public static String get(String uri, Map<String, Object> params, Map<String, String> headers) throws IOException {
        HttpClient client = getHttpClient();
        return get(client, uri, params, headers);
    }

    public static String get(HttpClient client, String uri, Map<String, Object> params, Map<String, String> headers) throws IOException {
        String result = "";
        String fullUrl = buildUrlWithParams(uri, params);
        HttpGet httpGet = new HttpGet(fullUrl);

        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.addHeader(entry.getKey(), entry.getValue());
            }
        }
        HttpResponse httpResponse = client.execute(httpGet);
        InputStream input = httpResponse.getEntity().getContent();
        if (null != input) {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"))) {
                String line = "";
                while ((line = reader.readLine()) != null) {
                    result += line;
                }
            } catch (IOException e) {
                throw e;
            }
        }
        return result;
    }

    public static String post(String uri, Map<String, String> params) {
        CloseableHttpClient httpClient = getHttpClient();

        return post(httpClient, uri, params, null);

    }

    public static String post(String uri, Map<String, String> params, Map<String, String> headers) {
        return post(getHttpClient(), uri, params, headers);
    }

    public static String post(HttpClient client, String uri, Map<String, String> params, Map<String, String> headers) {
        String result = "";

        HttpPost httpPost = new HttpPost(uri);
        List<NameValuePair> formparams = new ArrayList<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            //给参数赋值
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        httpPost.setEntity(entity);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }
        }
        try {
            HttpResponse httpResponse = client.execute(httpPost);
            InputStream input = httpResponse.getEntity().getContent();
            if (null != input) {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"))) {
                    String line = "";
                    while ((line = reader.readLine()) != null) {
                        result += line;
                    }
                } catch (IOException e) {
                    throw e;
                }
            }
            return result;
        } catch (IOException e) {
            throw new RRException("POST请求失败", e);
        }
    }


    public static String post(String uri, String content, Map<String, String> headers) throws IOException {
        String result = "";
        CloseableHttpClient client = getHttpClient();
        HttpPost httpPost = new HttpPost(uri);

        StringEntity entity = new StringEntity(content, Consts.UTF_8);
        httpPost.setEntity(entity);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }
        }
        HttpResponse httpResponse = client.execute(httpPost);
        InputStream input = httpResponse.getEntity().getContent();
        if (null != input) {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"))) {
                String line = "";
                while ((line = reader.readLine()) != null) {
                    result += line;
                }
            } catch (IOException e) {
                throw e;
            }
        }
        return result;
    }


    private static String buildUrlWithParams(String uri, Map<String, Object> params) throws UnsupportedEncodingException {
        StringBuilder urlBuilder = new StringBuilder(uri);
        if (null != params && !params.isEmpty()) {
            if (!uri.contains("?")) {
                urlBuilder.append("?");
            }
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                String valueStr = null == value ? "" : value.toString();
                if (!urlBuilder.toString().endsWith("?")) {
                    urlBuilder.append("&");
                }
                urlBuilder.append(key).append("=").append(URLEncoder.encode(valueStr, "utf-8"));
            }
        }
        String fullUrl = urlBuilder.toString();
        return fullUrl;
    }


}
